home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / ruby / 1.8 / open3.rb < prev    next >
Text File  |  2007-02-12  |  2KB  |  102 lines

  1. #
  2. # = open3.rb: Popen, but with stderr, too
  3. #
  4. # Author:: Yukihiro Matsumoto
  5. # Documentation:: Konrad Meyer
  6. #
  7. # Open3 gives you access to stdin, stdout, and stderr when running other
  8. # programs.
  9. #
  10.  
  11. #
  12. # Open3 grants you access to stdin, stdout, and stderr when running another
  13. # program. Example:
  14. #
  15. #   require "open3"
  16. #   include Open3
  17. #   
  18. #   stdin, stdout, stderr = popen3('nroff -man')
  19. #
  20. # Open3.popen3 can also take a block which will receive stdin, stdout and
  21. # stderr as parameters.  This ensures stdin, stdout and stderr are closed
  22. # once the block exits. Example:
  23. #
  24. #   require "open3"
  25. #
  26. #   Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
  27. #
  28.  
  29. module Open3
  30.   # 
  31.   # Open stdin, stdout, and stderr streams and start external executable.
  32.   # Non-block form:
  33.   #   
  34.   #   require 'open3'
  35.   #
  36.   #   [stdin, stdout, stderr] = Open3.popen3(cmd)
  37.   #
  38.   # Block form:
  39.   #
  40.   #   require 'open3'
  41.   #
  42.   #   Open3.popen3(cmd) { |stdin, stdout, stderr| ... }
  43.   #
  44.   # The parameter +cmd+ is passed directly to Kernel#exec.
  45.   #
  46.   def popen3(*cmd)
  47.     pw = IO::pipe   # pipe[0] for read, pipe[1] for write
  48.     pr = IO::pipe
  49.     pe = IO::pipe
  50.  
  51.     pid = fork{
  52.       # child
  53.       fork{
  54.     # grandchild
  55.     pw[1].close
  56.     STDIN.reopen(pw[0])
  57.     pw[0].close
  58.  
  59.     pr[0].close
  60.     STDOUT.reopen(pr[1])
  61.     pr[1].close
  62.  
  63.     pe[0].close
  64.     STDERR.reopen(pe[1])
  65.     pe[1].close
  66.  
  67.     exec(*cmd)
  68.       }
  69.       exit!(0)
  70.     }
  71.  
  72.     pw[0].close
  73.     pr[1].close
  74.     pe[1].close
  75.     Process.waitpid(pid)
  76.     pi = [pw[1], pr[0], pe[0]]
  77.     pw[1].sync = true
  78.     if defined? yield
  79.       begin
  80.     return yield(*pi)
  81.       ensure
  82.     pi.each{|p| p.close unless p.closed?}
  83.       end
  84.     end
  85.     pi
  86.   end
  87.   module_function :popen3
  88. end
  89.  
  90. if $0 == __FILE__
  91.   a = Open3.popen3("nroff -man")
  92.   Thread.start do
  93.     while line = gets
  94.       a[0].print line
  95.     end
  96.     a[0].close
  97.   end
  98.   while line = a[1].gets
  99.     print ":", line
  100.   end
  101. end
  102.